/**
 * 计时器挂件第三层: 流星 (原名: 颗粒层)
 *
 * 包含两类动画
 * A 类, 计时器播放时的动画，有从左到右的方格运动模糊动画
 * B 类，模拟进度条动画
 */

import MyTimer from './myTimer';

class Meteors {

  // config
  parent = null;
  zrender = null;
  zrInstance = null;
  /** @type {MyTimer} */
  timer = null;
  lastTickTime = 0;

  // UI
  /**
   * 运动模糊方格组, 它是一个数组, 每个元素是一个 object:
   * {
   *   array: <array> 一组方块
   *   offset: 每个方块的横坐标 x 的差值
   *   size: <integer> 方块的大小
   * }
   */
  blurs = [];
  /**
   * 控制白色方块的出现时间 / 间隔
   */
  countdown = 0;
  /**
   * 控制进度条, 上一次画条时的时间
   */
  progress = 120;

  constructor(options) {
    this.parent = options.parent;
    this.zrender = options.zrender;
    this.zrInstance = options.zrInstance;
    this.timer = options.timer;
    // TODO
  };

  start() {
    this.countdown = 50;
    this.progress = 120;
    this.lastTickTime = new Date().getTime();
  };

  stop() {
    // TODO
    let len = this.blurs.length;
    for (let i = 0; i < len; i++) {
      let o = this.blurs[i];
    
      let count = o.array.length;
      for (let j = 0; j < count; j++) {
        let el = o.array[j];
        this.remove(el);
      }
    }

    this.blurs = [];
  };

  remove(el) {
    let self = this;
    el.animate('style', false)
      .when(500, {
        opacity: 0
      }).done(function (){
        self.zrInstance.remove(el);
      }).start();
  };

  tick() {
    // 原来是 50fps, 现在改成 requestAnimationFrame 帧数就不固定了, 所以需要转换一次
    let now = new Date().getTime();
    // 最多跳三帧
    this.lastTickTime = Math.max(now - 20 * 3, this.lastTickTime);
    while (now - this.lastTickTime >= 20) {
      this.tickFrame();
      this.lastTickTime += 20;
    }
  }

  tickFrame() {
    /** @type {number} */
    let canvsWidth = this.parent.width;
    /** @type {number} */
    let canvsHeight = this.parent.height;


    if (!this.timer.playing || this.timer.pauseDelta >= 0) {
      return;
    }

    // 移动已经出现的方块
    let len = this.blurs.length;
    for (let i = 0; i < len; i++) {
      let count = this.blurs[i].array.length;
      for (let j = 0; j < count; j++) {
        let o = this.blurs[i];
        let el = o.array[j];
        let position = el.attr().position;
        el.attr({position:[position[0] + o.size, position[1]]});
      }
    }

    // 删除出界的方块
    for (let i = len - 1; i >= 0; i--) {
      let o = this.blurs[i];
      let y = o.array[0].attr().position[0];
      if (y >= canvsWidth + 12 * o.size) {
        // delete
        let count = this.blurs[i].array.length;
        for (let j = 0; j < count; j++) {
          let el = this.blurs[i].array[j];
          this.zrInstance.remove(el);
        }
        this.blurs.splice(i, 1);
        continue;
      }
    }

    // 计算是否出现方块
    this.countdown --;
    if (this.countdown <= 0) {
      // 出现方块
      let size = parseInt(Math.random() * 4 + 4);
      let o = {
        array: [],
        offset: size,
        size: size
      };
      let y = parseInt(Math.random() * (canvsHeight - size));
      let count = 12; // 一共出现多少个模糊的重影
      for (let i = 0; i < count; i++) {
        let el = new this.zrender.Rect({
          shape: {
            width: size,
            height: size
          },
          style: {
            fill: '#FFF',
            opacity: 0.6 - i * 0.05
          },
          position: [-1 * size * i, y],
          z: -3
        });
        this.zrInstance.add(el);
        o.array.push(el);
      }
      this.blurs.push(o);

      // 计算下一次出现方块的时间
      this.countdown = parseInt(Math.random() * 30 + 1);
    }

    // 进度条部分
    var self = this;
    var time = this.timer.s * 2 + ((this.timer.ds >= 5) ? 1 : 0);
    if (//this.m % 3 == 2 &&
      time != this.progress) {
      // 可以画
      var el = new this.zrender.Rect({
        shape: {
          width: canvsWidth / 120,
          height: canvsHeight
        },
        style: {
          fill: '#FFF',
          opacity: 0
        },
        position: [canvsWidth / 120 * time, 0],
        z: -3
      });
      this.zrInstance.add(el);
      el.animate('style', false)
        .when(500, {
          opacity: 0.5
        }).when(1000, {
          opacity: 0.2
        }).when(4000, {
          opacity: 0
        }).done(function (){
          self.zrInstance.remove(el);
        }).start();

      this.progress = time;
    }
  };

  destroy() {
    // no-thing
  };
}

export default Meteors;
